namespace Test.Robotics.Hardware
{
    using System;
    using System.Collections.Generic;
    using Microsoft.Robotics.Hardware.Runtime.Sensors;
    using Microsoft.Robotics.Hardware.Visualization;
    using Microsoft.Robotics.Runtime;
    using Microsoft.Robotics.Visualization;

    /// <summary>
    /// Sensor manifest helper
    /// </summary>    
    public static class SensorsManifest
    {
        /// <summary>
        /// Adds VectorNav sensor to the manifest
        /// </summary>
        /// <param name="manifest">Manifest to add to</param>
        /// <param name="timerAgent">Poll timer</param>
        /// <param name="comPort">COM port on which device sits</param>
        /// <param name="baudRate">Baud rate. Leave the default unless you know what you are doing</param>
        /// <returns>Attitude reading producer</returns>
        public static IProducer<AttitudeSensorMessage> AddVN100SensorToManifest(Manifest manifest, IProducer<TimerMessage> timerAgent, string comPort, int baudRate = 115200)
        {
            /* Full snippet of creating a running manifest with attitude sensor agent and UI
                
                var testMan = new Manifest();
                var views = new List<ViewDefinition>();
                
                TimerAgent timer = new TimerAgent("PollingTimer", 20, 1);
                testMan.Agents.Add(timer);
                testMan.ActiveAgents.Add(timer.Name);
              
                var sensorAgent = SensorsManifest.AddVN100SensorToManifest(testMan, timer, "COM9");
                SensorsManifest.AddSensorViewToManifest(testMan, views, sensorAgent);

                UserInterfaceAgent userInterface = new UserInterfaceAgent("UserInterface", views.ToArray());
                testMan.Agents.Add(userInterface);
                testMan.ActiveAgents.Add(userInterface.Name);
              
                Serializer.Save("Manifests\\Sensors.xml", testMan, testMan.GetKnownTypes());
            */

            VectorNavAttitudeSensorAgent vn100 = new VectorNavAttitudeSensorAgent(
                "VectorNavAttitudeSensorAgent",
                timerAgent,
                comPort,
                baudRate);

            manifest.Agents.Add(vn100);

            manifest.ActiveAgents.Add(vn100.Name);

            return vn100;
        }

        /// <summary>
        /// Adds Sensor view to the manifest. Currently only contains attitude information
        /// </summary>
        /// <param name="manifest">Manifest to add to</param>
        /// <param name="views">Views to add to</param>
        /// <param name="attitudeSensorAgent">Attitude sensor agent</param>
        public static void AddSensorViewToManifest(Manifest manifest, List<ViewDefinition> views, IProducer<AttitudeSensorMessage> attitudeSensorAgent)
        {
            SensorModelAgent attitudeModel = new SensorModelAgent(
                name: "SensorModelAgent",
                producer: attitudeSensorAgent,
                maxUpdateIntervalMilliseconds: 20);
            manifest.Agents.Add(attitudeModel);

            ViewDefinition attitudeView = new ViewDefinition(
                name: "Sensors",
                viewType: typeof(SensorView),
                modelAgent: attitudeModel);
            views.Add(attitudeView);
        }
    }
}
